﻿@using Newtonsoft.Json
@model Mvc4WebApiKoTb.Models.PersonModel

@{
    ViewBag.Title = "Person";
}

<div class="span12">
    <h2>Person - PersonModel</h2>
    <hr />
    <div class="well">Kurzer Beschreibungstext für das aktuelle Formular</div>
</div>
<div class="span12">
    @using (Html.BeginForm("Person", "Home", FormMethod.Post, new { @class = "form-horizontal" }))
    {
        <fieldset class="field1">
            @Html.ValidationSummary()

            <div class="control-group">
                @Html.LabelFor(model => model.Id, new { @class = "control-label" })

                <div class="controls">
                    @Html.TextBoxFor(model => model.Id, new { data_bind = "value: Id" })
                </div>
            </div>
            <div class="control-group">
                @Html.LabelFor(model => model.Vorname, new { @class = "control-label" })

                <div class="controls">
                    @Html.TextBoxFor(model => model.Vorname, new { data_bind = "value: Vorname" })
                    @Html.ValidationMessageFor(model => model.Vorname)
                </div>
            </div>
            <div class="control-group">
                @Html.LabelFor(model => model.Nachname, new { @class = "control-label" })

                <div class="controls">
                    @Html.TextBoxFor(model => model.Nachname, new { data_bind = "value: Nachname" })
                    @Html.ValidationMessageFor(model => model.Nachname)
                </div>
            </div>
            <div class="control-group">
                @Html.LabelFor(model => model.Birthdate, new { @class = "control-label" })

                <div class="controls">
                    @Html.TextBoxFor(model => model.Birthdate, new { data_bind = "dateValue: Birthdate" })
                    @Html.ValidationMessageFor(model => model.Birthdate)
                </div>
            </div>
            <div class="control-group">
                @Html.LabelFor(model => model.Starttime, new { @class = "control-label" })

                <div class="controls">
                    @Html.TextBoxFor(model => model.Starttime, new { data_bind = "timeValue: Starttime" })
                    @Html.ValidationMessageFor(model => model.Starttime)
                </div>
            </div>
            <div class="control-group">
                @Html.LabelFor(model => model.Ort, new { @class = "control-label" })

                <div class="controls">
                    @Html.TextBoxFor(model => model.Ort, new { data_bind = "value: Ort" })
                    @Html.ValidationMessageFor(model => model.Ort)
                </div>
            </div>
            <div class="form-actions">
                <input class="btn btn-primary" type="submit" value="Create" />
            </div>
        </fieldset>
    }
</div>

<div class="span12">
    <div class="well">
        @Html.ActionLink("Zurück zur Auflistung", "Index", null, new { @class = "btn btn-mini" })
    </div>
</div>

@section Scripts {
    @Scripts.Render("~/bundles/jqueryval")

    <script>
        jQuery.validator.methods.date = function (value, element) {
            return Globalize.parseDate(value);
        };

        $.validator.methods.number = function (value, element) {
            if (Globalize.parseFloat(value)) {
                return true;
            }
            return false;
        };

        jQuery(document).ready(function () {
            //Culture Einstellungen werden benötigt damit ein Valides Datum erkannt wird.
            Globalize.culture("de-DE");
            var dateformatStr = "DD.MM.YYYY", timeformatStr = "HH:mm";

            //Einbinden der Externen js Library für Datumsformate moment.js, ist auch unter NuGet verfügbar.
            //http://momentjs.com/docs/#/displaying/format/
            //http://denverdeveloper.wordpress.com/2012/10/02/knockout-helpful-date-time-tips/
            //Eigene bindinghandler für das Datumsformat für knockoutjs erstellen
            ko.bindingHandlers.dateValue = {
                init: function (element, valueAccessor, allBindingsAccessor) {
                    //die ValueBindings Handler von Knockout verwenden.
                    ko.bindingHandlers.value.init(element, valueAccessor, allBindingsAccessor);

                    //Das Passende Ausgabeformat festgelegen.
                    var value = valueAccessor(), strDate = ko.utils.unwrapObservable(value);
                    if (strDate) {
                        var date = moment(strDate);
                        if (date.isValid()) {
                            $(element).val(date.format(dateformatStr));
                        }
                    }
                },
                update: function (element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) {
                    var value = valueAccessor(), strDate = ko.utils.unwrapObservable(value);
                    if (strDate) {
                        var date = moment(strDate);
                        if (!date.isValid()) {
                            date = moment(strDate, dateformatStr);
                        }

                        if (date.isValid()) {
                            //Hier kann das Datum direkt als ISO Format String abgelegt werden.
                            //das passende Property wird dabei anhand der ElementId ermittelt.
                            bindingContext.$data[element.id](date.format());
                            //Value binding einstellen - wird benötigt, da sonst unsere custom
                            //UpdateFunktion nicht aufgerufen wird, wenn wir unseren Wert ändern.
                            ko.bindingHandlers.value.update(element, valueAccessor, allBindingsAccessor);
                            //Den Formatierten Wert ausgeben
                            $(element).val(date.format(dateformatStr));
                            return;
                        }
                    }

                    //Den Standardwert wieder herstellen, der nicht Valide war.
                    $(element).val(strDate);
                    //Value binding einstellen
                    ko.bindingHandlers.value.update(element, valueAccessor, allBindingsAccessor);
                }
            };

            //Bindinghandler für die Uhrzeit erstellen.
            ko.bindingHandlers.timeValue = {
                init: function (element, valueAccessor, allBindingsAccessor) {
                    ko.bindingHandlers.value.init(element, valueAccessor, allBindingsAccessor);
                    var value = valueAccessor(), strTime = ko.utils.unwrapObservable(value);
                    if (strTime) {
                        var date = moment(strTime);
                        if (date.isValid()) {
                            $(element).val(date.format(timeformatStr));
                        }
                    }
                },
                update: function (element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) {
                    var value = valueAccessor(), strDate = ko.utils.unwrapObservable(value);

                    if (strDate) {
                        var date = moment(strDate);
                        if (!date.isValid()) {
                            date = moment(strDate, timeformatStr);
                        }

                        if (date.isValid()) {
                            //Neues "Datum" anlegen - damit hier die Passende Urhzeit gesetzt werden kann
                            //denn wir benötigen ein gültiges ISO Datum für einen erfolgreichen Postback.
                            var orgDate = moment();
                            //die passenden Stunden und Minuten aus der Textbox setzten und dann Serverseitig die 
                            //passende Uhrzeit zu "extrahieren"
                            orgDate.hours(date.hours());
                            orgDate.minutes(date.minutes());
                            bindingContext.$data[element.id](orgDate.format());
                            ko.bindingHandlers.value.update(element, valueAccessor, allBindingsAccessor);

                            $(element).val(date.format(timeformatStr));
                            return;
                        }
                    }

                    $(element).val(strDate);
                    //Value binding einstellen
                    ko.bindingHandlers.value.update(element, valueAccessor, allBindingsAccessor);
                }
            };

            var mod12 = ko.mapping.fromJS(@(Html.Raw(JsonConvert.SerializeObject(Model))));
            ko.applyBindings(mod12);

            //Funktion die aufgerufen wird, wenn das Objekt erfolgreich angelegt werden konnte
            function CreatedSuccess(data) {
                //Das Model neu "binden" um die Daten auf der Oberfläche zu aktualisieren
                ko.applyBindings(data);
            }

            //Submit der Formulars und der Daten aus dem Model
            $("form").submit(function (event) {
                event.preventDefault();
                var model = JSON.stringify(ko.toJS(mod12));

                $.ajax({
                    //url: "/api/personEditApi/SaveWithParams?take=10&skip=20",
                    url: "/api/personEditApi/SavePerson",
                    //url: "/api/personEditApi/Save",
                    type: "POST",
                    data: model,
                    contentType: 'application/json; charset=utf-8',
                    statusCode: {
                        200 /* OK */: function (data) {
                            CreatedSuccess(data);
                        },
                        201 /* Created */: function (data) {
                            CreatedSuccess(data);
                        },
                        //400 /* BadRequest*/: function () {
                        //    //Die ModelRevalidation wird automatisch aufgerufen, 
                        //    //die Untersuchung auf Bad Request ist nicht notwendig.
                        //    //Es muss nur die Klasse "ValidateAttribute" für die 
                        //    //WebApi Registriert werden.
                        //}
                    }
                });
            });
        });
    </script>
}
